#ifndef __CANYON_CORE_REGISTERS
#define __CANYON_CORE_REGISTERS

#include "arch.hpp"

namespace canyon{

class Registers{
    protected:
    uint8_t pool[reg::end][REGISTER_SIZE] = {};

    public:

    bool verify_read(regid_t regid){
        if(regid<reg::end){
            return true;  // 临时不作地址权限验证
        }else return false;
    }

    bool verify_write(regid_t regid){
        if(regid<reg::end && regid != reg::CODE && regid != reg::EMPTY){
            return true;  // 临时不作地址权限验证
        }else return false;
    }

    public:

    uint64_t root_get_full(regid_t regid){
        if(regid == reg::EMPTY)return 0;
        uint64_t *tmp = reinterpret_cast<uint64_t *>(this->pool[regid]);
        return   *tmp;
    }

    void root_set_full(regid_t regid, uint64_t value){
        uint64_t *tmp = reinterpret_cast<uint64_t *>(this->pool[regid]);
        *tmp          = value;
    }

    public:

    uint8_t get(regid_t regid, size_t index){
        if(this->verify_read(regid)){
            if(regid == reg::EMPTY)return 0;
            
            return this->pool[regid][index];
        }else{
            // 异常回调中断，临时不作处理
            return 0;
        }
    }

    void set(regid_t regid, size_t index, uint8_t value){
        if(this->verify_write(regid)){
            this->pool[regid][index] = value;
        }else{
            // 异常回调中断，临时不作处理
        }
    }

    uint16_t get_16(regid_t regid, size_t index){
        if(this->verify_read(regid)){
            if(regid == reg::EMPTY)return 0;

            uint16_t *tmp = reinterpret_cast<uint16_t *>(this->pool[regid]);
            return   *(tmp + index);
        }else{
            // 异常回调中断，临时不作处理
            return 0;
        }
    }

    void set_16(regid_t regid, size_t index, uint16_t value){
        if(this->verify_write(regid)){
            uint16_t *tmp = reinterpret_cast<uint16_t *>(this->pool[regid]);
            *(tmp + index) = value;
        }else{
            // 异常回调中断，临时不作处理
        }
    }

    uint64_t get_full(regid_t regid){
        if(this->verify_read(regid)){
            return this->root_get_full(regid);
        }else{
            // 异常回调中断，临时不作处理
            return 0;
        }
    }

    void set_full(regid_t regid, uint64_t value){
        if(this->verify_write(regid)){
            this->root_set_full(regid, value);
        }else{
            // 异常回调中断，临时不作处理
        }
    }

    public:
    uint64_t * unsafe_get_adr(regid_t regid){
        uint64_t *tmp = reinterpret_cast<uint64_t *>(this->pool[regid]);
        return    tmp;
    }
};

}

#endif
